package org.jmc.refmanager.domain.model;

import java.beans.PropertyChangeSupport;
import java.io.Serializable;
import java.io.StringWriter;
import java.util.Date;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.PostLoad;
import javax.persistence.PrePersist;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.validation.constraints.Digits;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

import org.hibernate.envers.Audited;
import org.hibernate.envers.NotAudited;
import org.jmc.refmanager.util.BeanUtil;
import org.jmc.refmanager.util.Update;
import org.jmc.refmanager.util.UpdatesList;
import org.jmc.refmanager.util.UpdatesList.UpdateType;
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;

/**
 * Entity implementation class for Entity: Service
 * 
 */
@Entity
@Table(name = "service")
@NamedQueries({
	@NamedQuery(name = OrgUnit.FIND_TYPE_C02, query = "SELECT ou FROM OrgUnit ou WHERE ou.type='C02'"),
	@NamedQuery(name = OrgUnit.FIND_DIRECTION_VALIDATION, 
			query = "SELECT ou1 FROM OrgUnit ou1, OrgUnit ou2 WHERE ou2.id = :id AND ou1.type='C02'"
				+ " AND CONCAT_WS('.', ou2.parentPath, LPAD(ou2.id, 5, '0')) LIKE CONCAT(CONCAT_WS('.', ou1.parentPath, LPAD(ou1.id, 5, '0')), '%')"),
	@NamedQuery(name = OrgUnit.FIND_MY_CHILDREN, 
			query = "SELECT s FROM OrgUnit s fetch all properties WHERE s.parentPath LIKE ?1"),
	@NamedQuery(name = OrgUnit.FIND_DIRECT_CHILDREN, 
			query = "SELECT s FROM OrgUnit s fetch all properties WHERE s.parent.id = ?1 and s.supprime=false"),
	@NamedQuery(name = OrgUnit.COUNT_DIRECT_CHILDREN, 
			query = "SELECT COUNT(*) FROM OrgUnit s WHERE s.parent.id = ?1 and s.supprime=false"),
	@NamedQuery(name=OrgUnit.UPDATE_SET_DELETED,
			query = "UPDATE OrgUnit" +
			" SET supprime=true, motifSuppression = ?1" +
			" WHERE parentPath=?2 OR parentPath LIKE ?3 OR id=?4"),
	@NamedQuery(name = OrgUnit.COUNT_CHANGE_ON_TASK, 
			query = "SELECT COUNT(*) FROM OrgUnit s join s.changes c WHERE s.id = ?1")
    /*
	 * Ancetres:
	 * SELECT e1.id, e1.codeUO, e1.libCourt, e1.libComplet, e1.depth, e1.type, e1.parentPath
	 * FROM service e1, service e2
	 * WHERE CONCAT_WS('.', e2.parentPath, e2.id) LIKE CONCAT(CONCAT_WS('.', e1.parentPath, e1.id), '%') AND e2.id = 19813
	 * ORDER BY e1.depth
	 * 
	 * Direction de validation
	 * SELECT e1.id, e1.codeUO, e1.libCourt, e1.libComplet, e1.depth, e1.type, e1.parentPath
	 * FROM service e1, service e2
	 * WHERE CONCAT_WS('.', e2.parentPath, e2.id) LIKE CONCAT(CONCAT_WS('.', e1.parentPath, e1.id), '%') AND e2.id = 19813 AND e1.type='C02'
	 * 
	 */
	/*
		@NamedQuery(name = "Service.findByPrimaryKey", query = "SELECT e FROM OrgUnit e WHERE e.id = :id"),
		@NamedQuery(name = "Service.findAll", query = "SELECT e FROM OrgUnit e"),
		@NamedQuery(name = "Service.countServices", query = "SELECT count(*) FROM OrgUnit e"),
		@NamedQuery(name = "Service.findChildren", // s.id, s.libCourt, s.libComplet, s.codeUO, s.depth ORDER BY CONCAT_WS('.', s.parentPath, s.id)
				query = "SELECT s FROM OrgUnit s WHERE s.parentPath LIKE :parentPath ORDER BY CONCAT_WS('.', s.parentPath, s.id)"),
		@NamedQuery(name = "Service.setDeleteFlag",
				query = "UPDATE OrgUnit SET supprime = :isDeleted, motifSuppression = :motif WHERE parentPath LIKE :parentPath"),
		@NamedQuery(name = "Service.deleteHierarchy",
				query = "DELETE FROM OrgUnit s WHERE s.parentPath LIKE :parentPath")
*/
})
@Audited
@Root(name="service")
public class OrgUnit implements Serializable, Cloneable {
	private static final long serialVersionUID = 1L;
	private static final String PATH_SEP = ".";
	private static final Integer ROOT_ID = 0;
	private static final String ROOT_PATH = String.valueOf(ROOT_ID);
	public static final String HIERARCHY_DEPTH = "[^" + PATH_SEP + "]";

	public static final String FIND_TYPE_C02 = "OrgUnit.FindTypeC02";
	public static final String FIND_DIRECTION_VALIDATION = "OrgUnit.FindDirectionValidation";
	public static final String FIND_MY_CHILDREN = "OrgUnit.FindMyChildren";
	public static final String FIND_DIRECT_CHILDREN = "OrgUnit.FindDirectChildren";
	public static final String COUNT_DIRECT_CHILDREN = "OrgUnit.CountDirectChildren";
	public static final String UPDATE_SET_DELETED = "OrgUnit.UpdateSetDeleted";
	public static final String COUNT_CHANGE_ON_TASK = "OrgUnit.CountChangeOnTask";
	
	public enum Complement {
		B, T, Q
	}

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Attribute(name="id", required=false)
	private Integer id;
	
	@Column
	@NotNull
	@Size(min = 1, max = 20, message="Le libellé court contient au plus {max} caractères")
	@Element(required=false)
	private String libCourt;
	
	/**
	 * Path from root or lineage
	 */
	@Transient
	private String path;

	/**
	 * Parent object reference
	 */
	@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
	@JoinColumns( { @JoinColumn(name = "parentId") })
	private OrgUnit parent;

	// Utiliser pour la serialisation uniquement
	@Transient
	@Element(name="parentId", required=false)
	private Integer parentId;
	
	@Column
	@Element(required=false)
	private String parentPath;

	@Element(required=false)
	private Integer depth;

	@NotNull
	@Column(length = 10)
	@Element(required=true)
	private String codeUO;
	
	@Column(nullable = false, length = 1)
	@Element(required=false)
	private boolean saa;
	
	@Column(nullable = false, length = 1)
	@Element(required=false)
	private boolean sao;
	
	@Temporal(TemporalType.DATE)
	@Column(updatable = false)
	@Element(required=false)
	private Date dateCreation;
	
	@Column(length = 3)
	@Element(required=false)
	@Size(max=3)
	private String type;
	
	@Element(required=false)
	private boolean libModifie;
	
	@Element(required=false)
	@Size(min=1, max=60, message="Le libellé long contient au plus {max} caractères")
	private String libLong;
	
	@Element(required=false)
	@Size(min=1, max=254, message="Le libellé extra long contient au plus {max} caractères")
	private String libComplet;
	
	@Element(required=false)
	private String commentaire;
	
	@Element(required=false)
	private boolean modifAdresse;
	
	@Element(required=false)
	@Pattern(regexp="[0-9]{0,4}", message="Le numéro de rue contient 4 chiffres maximum")
	private String numRue;
	
	@Enumerated(EnumType.STRING)
	@Element(required=false)
	private Complement complementNumRue;
	
	@Element(required=false)
	@Size(max=26, message="Le nom de la rue ne doit pas dépasser {max} caractères")
	private String adresse;
	
	@Element(required=false)
	@Size(max=32, message="Le complément d'adresse ne doit pas dépasser {max} caractères")
	private String complementAdresse;
	
	@Element(required=false)
	private String commune;
	
	@Element(required=false)
	private String insee;
	
	@Element(required=false)
	@Digits(integer=5, fraction=0)
	private String codePostal;
	
	@Element(required=false)
	@Size(min=2, max=2)
	private String departement;
	
	@Element(required=false)
	@Size(min=2, max=2)
	private String dialogDepartement;
	
	@Element(required=false)
	@Size(min=3, max=3)
	private String tgDepartement;
	
	@Element(required=false)
	private String region;
	
	@Element(required=false)
	private boolean secteurDifficile;

	@Temporal(TemporalType.DATE)
	@Element(required=false)
	private Date dateEffet1;
	
	@Temporal(TemporalType.DATE)
	@Element(required=false)
	private Date dateEffet2;
	
	@Temporal(TemporalType.DATE)
	@Element(required=false)
	private Date dateFin;
	
	@Element(required=false)
	private String codeRegroupement;
	
	@Element(required=false)
	private String sgapRH;
	
	@Element(required=false)
	private String sgapFIN;
	
	@Element(required=false)
	private boolean droitMaj;
	
	@Element(required=false)
	private String dirNivC01;
	
	@Element(required=false)
	private String dirNivC02;
	
	@Element(required=false)
	private String dirNivL01;
	
	@Element(required=false)
	private String dirNivL02;
	
	@Element(required=false)
	private String asa;
	
	@Element(required=false)
	private String mail;
	
	@Element(required=false)
	@Pattern(regexp="\\d{10}", message="Le numéro de téléphone doit comporter 10 chiffres")
	private String telephone;
	
	@Element(required=false)
	private String rescom;

	@Element(required=false)
	private boolean cree;
	
	@Element(required=false)
	@Size(max=255, message="La longueur du motif ne doit pas dépasser {max} caractères")
	private String motifCreation;
	
	@Element(required=false)
	private boolean supprime;
	
	@Element(required=false)
	private boolean deplace;
	
	@Element(required=false)
	@Size(max=255, message="La longueur du motif ne doit pas dépasser {max} caractères")
	private String motifSuppression;

	/*
	 * Date de modification
	 */
	@Element(required=false)
	private Date modificationDate;

	@Element(required=false)
	@Size(max=38, message="La longueur de l'adresse postale ne pas dépasser {max} caractères")
	private String adressePostale;
	
//	@OneToMany(mappedBy = "validationScope")
//	@NotAudited
//	private Set<User> approvers = new HashSet<User>(0);

	// -------------------------------------------------
	// Donnees pour la gestion des changements
	// -------------------------------------------------
	@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL)
	@JoinTable(name = "service_changes", 
			joinColumns = { @JoinColumn(name = "id") },
			inverseJoinColumns = { @JoinColumn(name = "changeId") })
	@NotAudited
	private Set<Change> changes = new HashSet<Change>(0);

	// -------------------------------------------------
	// Gestion de la modification des propriétés de l'objet
	// -------------------------------------------------
	@Transient
	private final PropertyChangeSupport labelPropChange = new PropertyChangeSupport(this);
	@Transient
	private final PropertyChangeSupport addressPropChange = new PropertyChangeSupport(this);
	@Transient
	private final PropertyChangeSupport parentPropChange = new PropertyChangeSupport(this);
	@Transient
	private final PropertyChangeSupport otherPropChange = new PropertyChangeSupport(this);
	
	@Transient
	private final UpdatesList updatesList;
	
	// -------------------------------------------------
	// CONSTRUCTEUR
	// -------------------------------------------------
	public OrgUnit() {
		super();
		
		updatesList = new UpdatesList();
		
		// Changement sur les propriétés affectant le libelle
		labelPropChange.addPropertyChangeListener(
				updatesList.getUpdateOf(UpdateType.LABEL));
		
		// Changement sur les propriétés affectant l'adresse
		addressPropChange.addPropertyChangeListener(
				updatesList.getUpdateOf(UpdateType.ADDRESS));

		// Changement sur les propriétés affectant le code parent
		parentPropChange.addPropertyChangeListener(
				updatesList.getUpdateOf(UpdateType.PARENT));

		// Changement sur les propriétés affectant le code parent
		otherPropChange.addPropertyChangeListener(
				updatesList.getUpdateOf(UpdateType.OTHER));
	}

	/**
	 * 
	 * @return
	 */
	public String getSerializedChanges() {
		this.updatesList.setServiceId(id);
		return BeanUtil.getSerializedBean(this.updatesList.trim());
	}

	/**
	 * 
	 * @param propertyName
	 * @return
	 */
	public Object getBeforeValue(String propertyName) {
		Object value = null;
		if (updatesList.containsUpdateAttribute(propertyName)) {
			// return la valeur avant mise à jour
			Update update = updatesList.getUpdate(propertyName);
			value = update.getBeforeValue(propertyName);
		} else {
			// retourne la valeur mise à jour
			value = BeanUtil.getProperty(this, propertyName);
		}
		
		return value;
	}
	
	/**
	 * 
	 * @return
	 */
	public UpdatesList getUpdates() {
		// Filtrer les changements vides
		return this.updatesList.trim();
	}
	
	/**
	 * 
	 * @return
	 */
	public boolean hasUpdates() {
		boolean hasUpdate = false;
		UpdateType[] updateTypes = UpdateType.values();
		for (UpdateType updateType : updateTypes) {
			hasUpdate |= this.updatesList.containsUpdateOf(updateType);
		}
		return hasUpdate;
	}
	
	/**
	 * Applique les mises à jour sauf celles concernant un deplacement
	 * 
	 * @param xmlChanges
	 */
	public void applySerializedChanges(String xmlChanges) {
		UpdatesList propertyChanges = BeanUtil.getDeserializedBean(xmlChanges, UpdatesList.class);
		
		for (Update update : propertyChanges.getAllUpdatesWithNoMove()) {
			Map<String, Object> attrsUpdates = update.getAttributeUpdates();
			for (Entry<String, Object> attr : attrsUpdates.entrySet()) {
				BeanUtil.setProperty(this, attr.getKey(), attr.getValue());
			}
		}
	}

	// -------------------------------------------------
	// CYCLE DE VIE JPA
	// -------------------------------------------------
	@PrePersist
	protected void prePersit() {
		this.setDateCreation(new Date());
		this.setCodeRegroupement("PN");
		this.setCree(true);
		this.addParentPath();
		// Hierarchy depth is the number of separator !
		int countSep = this.getParentPath().replaceAll(HIERARCHY_DEPTH, "").length();
		this.setDepth(countSep);
	}

	protected void addParentPath() {
		if (this.getParent() == null) {
			setParentPath(ROOT_PATH);
		} else {
			setParentPath(this.getParent().getPath());
		}
	}

	@PostLoad
	protected void setMaterializedPath() {
		StringBuilder builder = new StringBuilder();
		builder.append(this.getParentPath());
		//builder.append(PATH_SEP).append(this.getId());
		builder.append(PATH_SEP).append(String.format("%05d", this.getId()));
		this.path = builder.toString();
	}

	// -------------------------------------------------
	// SERIALISATION DE L'OBJECT
	// -------------------------------------------------
	/**
	 * @TODO A externaliser ou e mettre en static
	 * @return
	 */
	public String getSerializedBean() {
		Serializer serializer = new Persister();
		StringWriter writer = new StringWriter();
		
		try {
			serializer.write(this, writer);
		} catch (Exception e) {
			throw new IllegalStateException("Impossible de sérialiser l'objet", e);
		}

		StringBuffer xml = writer.getBuffer();
		return xml.toString();
	}
	
	// -------------------------------------------------
	// GETTERS and SETTERS
	// -------------------------------------------------
	public Integer getId() {
		return this.id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getLibCourt() {
		return this.libCourt;
	}

	public void setLibCourt(String libCourt) {
		String currentValue = this.getLibCourt();
		this.libCourt = libCourt;
		
		// Fires a property change event
		labelPropChange.firePropertyChange("libCourt", currentValue, libCourt);
	}

	public Integer getParentId() {
		if (parentId != null) {
			return parentId;
		} else if (this.getParent() == null) {
			return ROOT_ID;
		} else {
			return this.getParent().getParentId();
		}
	}

	public String getPath() {
		if (this.path == null) {
			setMaterializedPath();
		}
		return this.path;
	}

	public Set<Change> getChanges() {
		return this.changes;
	}

	public void setChanges(Set<Change> changes) {
		this.changes = changes;
	}

	/**
	 * @return the parent
	 */
	public OrgUnit getParent() {
		return parent;
	}

	/**
	 * @param parent the parent to set
	 */
	public void setParent(OrgUnit parent) {
		Integer currentValue = 0;
		if (this.parent != null) {
			currentValue = this.getParent().getId();
		}
		this.parent = parent;
		if (parent != null) {
			this.parentId = parent.getId();
		} else {
			this.parentId = 0;
		}
		// Fires a property change event
		parentPropChange.firePropertyChange("parentId", currentValue, this.parentId);
	}

	/**
	 * @return the parentPath
	 */
	public String getParentPath() {
		return parentPath;
	}

	/**
	 * @param parentPath the parentPath to set
	 */
	public void setParentPath(String parentPath) {
		this.parentPath = parentPath;
	}

	/**
	 * @return the depth
	 */
	public Integer getDepth() {
		return depth;
	}

	/**
	 * @param depth the depth to set
	 */
	public void setDepth(Integer depth) {
		this.depth = depth;
	}

	/**
	 * @return the codeUO
	 */
	public String getCodeUO() {
		return codeUO;
	}

	/**
	 * @param codeUO the codeUO to set
	 */
	public void setCodeUO(String codeUO) {
		this.codeUO = codeUO;
	}

	/**
	 * @return the saa
	 */
	public boolean isSaa() {
		return saa;
	}

	/**
	 * @param saa the saa to set
	 */
	public void setSaa(boolean saa) {
		this.saa = saa;
	}

	/**
	 * @param saa the saa to set
	 */
	public void setSaa(Boolean saa) {
		setSaa(saa.booleanValue());
	}

	/**
	 * @return the sao
	 */
	public boolean isSao() {
		return sao;
	}

	/**
	 * @param sao the sao to set
	 */
	public void setSao(boolean sao) {
		this.sao = sao;
	}

	/**
	 * @param sao the sao to set
	 */
	public void setSao(Boolean sao) {
		setSao(sao.booleanValue());
	}

	/**
	 * @return the dateCreation
	 */
	public Date getDateCreation() {
		return dateCreation;
	}

	/**
	 * @param dateCreation the dateCreation to set
	 */
	public void setDateCreation(Date dateCreation) {
		this.dateCreation = dateCreation;
	}

	/**
	 * @return the type
	 */
	public String getType() {
		return type;
	}

	/**
	 * @param type the type to set
	 */
	public void setType(String type) {
		this.type = type;
	}

	/**
	 * @return the libModifie
	 */
	public boolean isLibModifie() {
		return libModifie;
	}

	/**
	 * @param libModifie the libModifie to set
	 */
	public void setLibModifie(boolean libModifie) {
		this.libModifie = libModifie;
	}

	/**
	 * @return the libLong
	 */
	public String getLibLong() {
		return libLong;
	}

	/**
	 * @param libLong the libLong to set
	 */
	public void setLibLong(String libLong) {
		String currentValue = this.getLibLong();
		this.libLong = libLong;
		
		// Fires a property change event
		labelPropChange.firePropertyChange("libLong", currentValue, libLong);
	}

	/**
	 * @return the libComplet
	 */
	public String getLibComplet() {
		return libComplet;
	}

	/**
	 * @param libComplet the libComplet to set
	 */
	public void setLibComplet(String libComplet) {
		String currentValue = this.getLibComplet();
		this.libComplet = libComplet;
		
		// Fires a property change event
		labelPropChange.firePropertyChange("libComplet", currentValue, libComplet);
	}

	/**
	 * @return the commentaire
	 */
	public String getCommentaire() {
		return commentaire;
	}

	/**
	 * @param commentaire the commentaire to set
	 */
	public void setCommentaire(String commentaire) {
		String currentValue = this.getCommentaire();
		this.commentaire = commentaire;
		// Fires a property change event
		otherPropChange.firePropertyChange("commentaire", currentValue, commentaire);
	}

	/**
	 * @return the modifAdresse
	 */
	public boolean isModifAdresse() {
		return modifAdresse;
	}

	/**
	 * @param modifAdresse the modifAdresse to set
	 */
	public void setModifAdresse(boolean modifAdresse) {
		this.modifAdresse = modifAdresse;
	}

	/**
	 * @return the numRue
	 */
	public String getNumRue() {
		return numRue;
	}

	/**
	 * @param numRue the numRue to set
	 */
	public void setNumRue(String numRue) {
		String currentValue = this.getNumRue();
		this.numRue = numRue;
		
		// Fires a property change event
		addressPropChange.firePropertyChange("numRue", currentValue, numRue);
	}

	/**
	 * @return the complementNumRue
	 */
	public Complement getComplementNumRue() {
		return complementNumRue;
	}

	/**
	 * @param complementNumRue the complementNumRue to set
	 */
	public void setComplementNumRue(Complement complementNumRue) {
		Complement currentValue = this.getComplementNumRue();
		this.complementNumRue = complementNumRue;
		
		// Fires a property change event
		addressPropChange.firePropertyChange("complementNumRue", currentValue, complementNumRue);
	}

	/**
	 * @return the adresse
	 */
	public String getAdresse() {
		return adresse;
	}

	/**
	 * @param adresse the adresse to set
	 */
	public void setAdresse(String adresse) {
		String currentValue = this.getAdresse();
		this.adresse = adresse;
		
		// Fires a property change event
		addressPropChange.firePropertyChange("adresse", currentValue, adresse);
	}

	/**
	 * @return the complementAdresse
	 */
	public String getComplementAdresse() {
		return complementAdresse;
	}

	/**
	 * @param complementAdresse the complementAdresse to set
	 */
	public void setComplementAdresse(String complementAdresse) {
		String currentValue = this.getComplementAdresse();
		this.complementAdresse = complementAdresse;
		
		// Fires a property change event
		addressPropChange.firePropertyChange("complementAdresse", currentValue, complementAdresse);
	}

	/**
	 * @return the commune
	 */
	public String getCommune() {
		return commune;
	}

	/**
	 * @param commune the commune to set
	 */
	public void setCommune(String commune) {
		String currentValue = this.getCommune();
		this.commune = commune;
		
		// Fires a property change event
		addressPropChange.firePropertyChange("commune", currentValue, commune);
	}

	/**
	 * @return the insee
	 */
	public String getInsee() {
		return insee;
	}

	/**
	 * @param insee the insee to set
	 */
	public void setInsee(String insee) {
		String currentValue = this.getInsee();
		this.insee = insee;
		
		// Fires a property change event
		addressPropChange.firePropertyChange("insee", currentValue, insee);
	}

	/**
	 * @return the codePostal
	 */
	public String getCodePostal() {
		return codePostal;
	}

	/**
	 * @param codePostal the codePostal to set
	 */
	public void setCodePostal(String codePostal) {
		String currentValue = this.getCodePostal();
		this.codePostal = codePostal;
		
		// Fires a property change event
		addressPropChange.firePropertyChange("codePostal", currentValue, codePostal);
	}

	/**
	 * @return the departement
	 */
	public String getDepartement() {
		return departement;
	}

	/**
	 * @param departement the departement to set
	 */
	public void setDepartement(String departement) {
		String currentValue = this.getDepartement();
		this.departement = departement;
		
		// Fires a property change event
		addressPropChange.firePropertyChange("departement", currentValue, departement);
	}

	/**
	 * @return the dialogDepartement
	 */
	public String getDialogDepartement() {
		return dialogDepartement;
	}

	/**
	 * @param dialogDepartement the dialogDepartement to set
	 */
	public void setDialogDepartement(String dialogDepartement) {
		String currentValue = this.getDialogDepartement();
		this.dialogDepartement = dialogDepartement;
		
		// Fires a property change event
		addressPropChange.firePropertyChange("dialogDepartement", currentValue, dialogDepartement);
	}

	/**
	 * @return the tgDepartement
	 */
	public String getTgDepartement() {
		return tgDepartement;
	}

	/**
	 * @param tgDepartement the tgDepartement to set
	 */
	public void setTgDepartement(String tgDepartement) {
		String currentValue = this.getTgDepartement();
		this.tgDepartement = tgDepartement;
		
		// Fires a property change event
		addressPropChange.firePropertyChange("tgDepartement", currentValue, tgDepartement);
	}

	/**
	 * @return the region
	 */
	public String getRegion() {
		return region;
	}

	/**
	 * @param region the region to set
	 */
	public void setRegion(String region) {
		String currentValue = this.getRegion();
		this.region = region;
		
		// Fires a property change event
		addressPropChange.firePropertyChange("region", currentValue, region);
	}

	/**
	 * @return the secteurDifficile
	 */
	public boolean isSecteurDifficile() {
		return secteurDifficile;
	}

	/**
	 * @param secteurDifficile the secteurDifficile to set
	 */
	public void setSecteurDifficile(boolean secteurDifficile) {
		this.secteurDifficile = secteurDifficile;
	}

	/**
	 * @return the dateEffet
	 */
	public Date getDateEffet1() {
		return dateEffet1;
	}

	/**
	 * @param dateEffet the dateEffet to set
	 */
	public void setDateEffet1(Date dateEffet) {
		this.dateEffet1 = dateEffet;
	}

	/**
	 * @return the dateEffet
	 */
	public Date getDateEffet2() {
		return dateEffet2;
	}

	/**
	 * @param dateEffet the dateEffet to set
	 */
	public void setDateEffet2(Date dateEffet) {
		this.dateEffet2 = dateEffet;
	}

	/**
	 * @return the dateFin
	 */
	public Date getDateFin() {
		return dateFin;
	}

	/**
	 * @param dateFin the dateFin to set
	 */
	public void setDateFin(Date dateFin) {
		Date currentValue = this.getDateFin();
		this.dateFin = dateFin;
		// Fires a property change event
		otherPropChange.firePropertyChange("dateFin", currentValue, dateFin);
	}

	/**
	 * @return the codeRegroupement
	 */
	public String getCodeRegroupement() {
		return codeRegroupement;
	}

	/**
	 * @param codeRegroupement the codeRegroupement to set
	 */
	public void setCodeRegroupement(String codeRegroupement) {
		String currentValue = this.getCodeRegroupement();
		this.codeRegroupement = codeRegroupement;
		// Fires a property change event
		otherPropChange.firePropertyChange("codeRegroupement", currentValue, codeRegroupement);
	}

	/**
	 * @return the sgapRH
	 */
	public String getSgapRH() {
		return sgapRH;
	}

	/**
	 * @param sgapRH the sgapRH to set
	 */
	public void setSgapRH(String sgapRH) {
		this.sgapRH = sgapRH;
	}

	/**
	 * @return the sgapFIN
	 */
	public String getSgapFIN() {
		return sgapFIN;
	}

	/**
	 * @param sgapFIN the sgapFIN to set
	 */
	public void setSgapFIN(String sgapFIN) {
		this.sgapFIN = sgapFIN;
	}

	/**
	 * @return the droitMaj
	 */
	public boolean isDroitMaj() {
		return droitMaj;
	}

	/**
	 * @param droitMaj the droitMaj to set
	 */
	public void setDroitMaj(boolean droitMaj) {
		this.droitMaj = droitMaj;
	}

	/**
	 * @return the dirNivC01
	 */
	public String getDirNivC01() {
		return dirNivC01;
	}

	/**
	 * @param dirNivC01 the dirNivC01 to set
	 */
	public void setDirNivC01(String dirNivC01) {
		this.dirNivC01 = dirNivC01;
	}

	/**
	 * @return the dirNivC02
	 */
	public String getDirNivC02() {
		return dirNivC02;
	}

	/**
	 * @param dirNivC02 the dirNivC02 to set
	 */
	public void setDirNivC02(String dirNivC02) {
		this.dirNivC02 = dirNivC02;
	}

	/**
	 * @return the dirNivL01
	 */
	public String getDirNivL01() {
		return dirNivL01;
	}

	/**
	 * @param dirNivL01 the dirNivL01 to set
	 */
	public void setDirNivL01(String dirNivL01) {
		this.dirNivL01 = dirNivL01;
	}

	/**
	 * @return the dirNivL02
	 */
	public String getDirNivL02() {
		return dirNivL02;
	}

	/**
	 * @param dirNivL02 the dirNivL02 to set
	 */
	public void setDirNivL02(String dirNivL02) {
		this.dirNivL02 = dirNivL02;
	}

	/**
	 * @return the asa
	 */
	public String getAsa() {
		return asa;
	}

	/**
	 * @param asa the asa to set
	 */
	public void setAsa(String asa) {
		this.asa = asa;
	}

	/**
	 * @return the mail
	 */
	public String getMail() {
		return mail;
	}

	/**
	 * @param mail the mail to set
	 */
	public void setMail(String mail) {
		String currentValue = this.getMail();
		this.mail = mail;
		
		// Fires a property change event
		addressPropChange.firePropertyChange("mail", currentValue, mail);
	}

	/**
	 * @return the telephone
	 */
	public String getTelephone() {
		return telephone;
	}

	/**
	 * @param telephone the telephone to set
	 */
	public void setTelephone(String telephone) {
		String currentValue = this.getTelephone();
		this.telephone = telephone;
		
		// Fires a property change event
		addressPropChange.firePropertyChange("telephone", currentValue, telephone);
	}

	/**
	 * @return the rescom
	 */
	public String getRescom() {
		return rescom;
	}

	/**
	 * @param rescom the rescom to set
	 */
	public void setRescom(String rescom) {
		String currentValue = this.getRescom();
		this.rescom = rescom;
		
		// Fires a property change event
		addressPropChange.firePropertyChange("rescom", currentValue, rescom);
	}

	/**
	 * @return the cree
	 */
	public boolean isCree() {
		return cree;
	}


	/**
	 * @param cree the cree to set
	 */
	public void setCree(boolean cree) {
		this.cree = cree;
	}

	/**
	 * @return the modifCreation
	 */
	public String getModifCreation() {
		return motifCreation;
	}

	/**
	 * @param modifCreation the modifCreation to set
	 */
	public void setModifCreation(String motifCreation) {
		this.motifCreation = motifCreation;
	}

	/**
	 * @return the supprime
	 */
	public boolean isSupprime() {
		return supprime;
	}

	/**
	 * @param supprime the supprime to set
	 */
	public void setSupprime(Boolean supprime) {
		this.setSupprime(supprime.booleanValue());
	}

	/**
	 * @param supprime the supprime to set
	 */
	public void setSupprime(boolean supprime) {
		boolean currentValue = this.isSupprime();
		this.supprime = supprime;
		// Fires a property change event
		otherPropChange.firePropertyChange("supprime", currentValue, supprime);
	}

	/**
	 * @return the motifSuppression
	 */
	public String getMotifSuppression() {
		return motifSuppression;
	}

	/**
	 * @param motifSuppression the motifSuppression to set
	 */
	public void setMotifSuppression(String motifSuppression) {
		String currentValue = this.getMotifSuppression();
		this.motifSuppression = motifSuppression;
		// Fires a property change event
		otherPropChange.firePropertyChange("motifSuppression", currentValue, motifSuppression);
	}

	/**
	 * @return the modificationDate
	 */
	public Date getModificationDate() {
		return modificationDate;
	}

	/**
	 * @param modificationDate the modificationDate to set
	 */
	public void setModificationDate(Date modificationDate) {
		this.modificationDate = modificationDate;
	}

	/**
	 * @return the deplace
	 */
	public boolean isDeplace() {
		return deplace;
	}

	/**
	 * @param deplace the deplace to set
	 */
	public void setDeplace(boolean deplace) {
		this.deplace = deplace;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return String
				.format("OrgUnit [id=%s, libCourt=%s, path=%s, parentId=%s, parentPath=%s, depth=%s, codeUO=%s, saa=%s, sao=%s, dateCreation=%s, type=%s, libModifie=%s, libLong=%s, libComplet=%s, commentaire=%s, modifAdresse=%s, numRue=%s, complementNumRue=%s, adresse=%s, complementAdresse=%s, commune=%s, insee=%s, codePostal=%s, departement=%s, dialogDepartement=%s, tgDepartement=%s, region=%s, secteurDifficile=%s, dateEffet1=%s, dateEffet2=%s, dateFin=%s, codeRegroupement=%s, sgapRH=%s, sgapFIN=%s, droitMaj=%s, dirNivC01=%s, dirNivC02=%s, dirNivL01=%s, dirNivL02=%s, asa=%s, mail=%s, telephone=%s, rescom=%s, cree=%s, motifCreation=%s, supprime=%s, deplace=%s, motifSuppression=%s, modificationDate=%s]",
						id, libCourt, path, parentId, parentPath, depth,
						codeUO, saa, sao, dateCreation, type, libModifie,
						libLong, libComplet, commentaire, modifAdresse, numRue,
						complementNumRue, adresse, complementAdresse, commune,
						insee, codePostal, departement, dialogDepartement,
						tgDepartement, region, secteurDifficile, dateEffet1,
						dateEffet2, dateFin, codeRegroupement, sgapRH, sgapFIN,
						droitMaj, dirNivC01, dirNivC02, dirNivL01, dirNivL02,
						asa, mail, telephone, rescom, cree, motifCreation,
						supprime, deplace, motifSuppression, modificationDate);
	}

	/**
	 * @return the motifCreation
	 */
	public String getMotifCreation() {
		return motifCreation;
	}

	/**
	 * @param motifCreation the motifCreation to set
	 */
	public void setMotifCreation(String motifCreation) {
		this.motifCreation = motifCreation;
	}

	/**
	 * @return the adressePostale
	 */
	public String getAdressePostale() {
		return adressePostale;
	}

	/**
	 * @param adressePostale the adressePostale to set
	 */
	public void setAdressePostale(String adressePostale) {
		String currentValue = this.getAdressePostale();
		this.adressePostale = adressePostale;

		// Fires a property change event
		addressPropChange.firePropertyChange("adressePostale", currentValue, adressePostale);
	}

}
